#ifndef REGION_H_
#define REGION_H_

//@Include: puzzle_region.h
//@Include: time_region.h

// INCLUDES //
#include "SDL/SDL.h"
#include "object.h"
#include "effect/region_effect.h"
#include "physics/boundary.h"
#include <vector>
//////////////

/**
* Contains objects within a boundary and delegates to them.
* 
* @see RegionEffectOwner
* @author dfoelber
**/
class Region
{
public:
	/**
	* Constructor
	**/
	Region();
	
	/**
	* Destructor
	**/
	virtual ~Region();
	
	/**
	* Sets the region's boundary.
	* 
	* @param x The boundary's X coordinate
	* @param y The boundary's Y coordinate
	* @param width The boundary's width
	* @param height The boundary's height
	**/
	virtual void SetBoundary( int x, int y, int width, int height );
	
	/**
	* Gets the region's boundary
	* 
	* @return The region's boundary
	**/
	Boundary* GetBoundary() { return &boundary; }
	
	/**
	* Checks if the region is dirty and requires a total update.
	* 
	* @return If the region is dirty
	**/
	bool IsDirty();
	
	/**
	* Sets the region to be dirty and requires a total update.
	* 
	* @param dirty If the region is dirty
	**/
	void SetDirty( bool dirty );
	
	/**
	* Checks if the region is visible.
	* 
	* @return If the region is visible
	**/
	bool IsVisible();
	
	/**
	* Sets the region's visibility.
	* 
	* @param visible If the region is visible
	**/
	virtual void SetVisible( bool visible );
	
	/**
	* Adds an object, the region becomes the owner.
	* 
	* @param object The object to add
	**/
	void AddObject( Object* object );

	/**
	* Gets the active object.
	* 
	* @return The active object
	**/
	Object* GetActiveObject();	
	
	/**
	* Sets the active object.
	* 
	* @param object The new active object
	**/
	void SetActiveObject( Object* object );
	
	/**
	* Gets the object in the object list.
	* 
	* @param index The index in the object list
	* @return The object in the specific position in the list
	**/
	Object* GetObject( int index );
	
	/**
	* Notify the region of an event.
	* 
	* @param event The event that happened
	* @return If the region used the event
	**/
	virtual bool ProcessEvent( SDL_Event event );
	
	/**
	* Notifies of time passing.
	* 
	* @param The amount of time, in milliseconds, that passed since the last call
	**/
	virtual void TimePassed( int ms );
	
	/**
	* A chance for a region to add a custom rendering request. Anything in the object list will
	* render automatically.
	**/
	virtual void Render();
	
	/**
	* Gets the list of objects in the region.
	* 
	* @region Objects currently in the region
	**/
	virtual vector<Object*>& GetObjects();
	
	/**
	* Checks if the object passed is the active object or in the active object's association list.
	* 
	* @param object The object to check
	* @return If the object is the active object or in the active object's association list
	**/
	virtual bool IsObjectActiveOrSimilar(Object* object);
	
	/**
	* Removes the given object from the region.
	* 
	* @param object The object to remove
	* @param del If the object should be deleted
	**/
	virtual void RemoveObject(Object* object, bool del = true);
	
	/**
	* Gets the object, if any, that correspond to the X,Y coordinates.
	* 
	* @param x The X coordinate
	* @param y The Y coordinate
	* @return The associated object, or null if none correspond
	**/
	virtual Object* GetObjectByCoordinate(int x, int y);

	/**
	* Gets the region's tooltip information.
	* 
	* @param The tooltip info
	**/
	virtual TooltipInfo* GetTooltipInfo();
	
	/**
	* Sets the current AI command.
	* 
	* @param command The new command
	**/
	void SetAICommand( int command ) { aiCommand = command; }
	
	/**
	* Gets the current AI command.
	* 
	* @return The current AI command
	**/
	int GetAICommand() { return aiCommand; }
	
protected:
	/**
	* Gets the current mouse X position.
	* 
	* @returns The current mouse X position
	**/
	virtual int GetMouseX() { return mouseX; }

	/**
	* Gets the current mouse Y position.
	* 
	* @returns The current mouse Y position
	**/
	virtual int GetMouseY() { return mouseY; }
	
	/**
	* Checks for a hoverring object.
	**/
	void CheckForHover();
	
private:
	/**
	* Checks and handles the possible collision between objects.
	* Will move the first if it collides with the second.
	* 
	* @param first The first object
	* @param second The second object
	**/
	void CheckCollision( Object* first, Object* second );
	
protected:
	/**
	* List of objects
	*/
	vector<Object*>				objects;
	
	/**
	* The active object
	**/
	Object*						active;
	
	/**
	* The object that the mouse is hovering
	**/
	Object*						hoverObject;
	
private:
	/**
	* The boundary
	**/
	Boundary					boundary;
	
	/**
	* If the region is dirty and requires an entire refresh
	**/
	bool						dirty;
	
	/**
	* If the region is visible
	**/
	bool						visible;
	
	/**
	* The current mouse X position
	**/
	int							mouseX;
	
	/**
	* The current mouse Y position
	**/
	int							mouseY;
	
	/**
	* The AI command
	**/
	int							aiCommand;
};

#endif /*REGION_H_*/
